前端安全

  1. CSRF 怎么防范?
  2. 中间人劫持,怎么防止。
    1. x-frame-option? (避免点击劫持) 白屏的喔,怎么办?也不一定嵌入 iframe 啊,可以嵌入脚本、图片,怎么阻止【描述】
    2. x-frame-option、重定向、https,请求前加密(https、加密代理)、请求中规避(请求拆包)、请求后弥补(前端做一些逻辑)。嵌入非 iframe 的,如果已经突破了前面两关,走前端逻辑:触发 DOMNodeInserted、DOMContentLoaded、DOMAttrModified 事件。或者是给能 src 的标签加上自己的 data-xx 属性标记区分。

XSS 跨站脚本攻击 Cross Site Scripting

利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到 web 页面中去。使别的用户访问都会执行相应的嵌入代码,从而盗取用户资料、利用用户身份。

类型

XSS攻击的核心原理是:不需要做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是jshtml代码块等)。

1. 反射型

发出请求时,XSS代码出现在url中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,所以叫反射型XSS

举个例子

一个链接,里面的 query 字段中包含一个 script 标签,这个标签的 src 就是恶意代码,用户点击了这个链接后会先向服务器发送请求,服务器返回时也携带了这个 XSS 代码,然后浏览器将查询的结果写入 Html,这时恶意代码就被执行了。

并不是在 url 中没有包含 script 标签的网址都是安全的,可以使用短网址来让网址变得很短。

2. 存储型

存储型XSS和反射型XSS的差别在于,提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求时目标页面时不用再提交 XSS 代码。

存储型 XSS 会被保存到数据库,在其他用户访问(前端)到这条数据时,这个代码会在访问用户的浏览器端执行。

举个例子

比如攻击者在一篇文章的评论中写入了 script 标签,这个评论被保存数据库,当其他用户看到这篇文章时就会执行这个脚本。

危害

  • 盗用Cookie
  • 破坏页面的正常结构,插入广告等恶意内容

XSS 攻击注入点

  • HTML 节点内容
    • 如果一个节点内容是动态生成的,而这个内容中包含用户输入。
  • HTML 属性
    • 某些节点属性值是由用户输入的内容生成的。那么可能会被封闭标签后添加 script 标签。
<img src="${image}" /> <img src="1" onerror="alert(1)" />
  • Javascript 代码
    • JS 中包含由后台注入的变量或用户输入的信息。
var data = "#{data}";
var data = "hello";
alert(1);
("");
  • 富文本

XSS 防御

对于 XSS 攻击来说,通常有两种方式可以用来防御。

  • 转义字符(encode)
  • CSP 内容安全策略
  • 设置 Cookie 为 HttpOnly

转义字符

  • 普通的输入 - 编码

    • 对用户输入数据进行 HTML Entity 编码(使用转义字符)
    • "
    • &
    • <
    • >
    • 空格
    • < 转义为 &lt;
    • 转义为 &gt;

  • 富文本 - 过滤(黑名单、白名单)

    • 移除上传的 DOM 属性,如 onerror 等
    • 移除用户上传的 style 节点、script 节点、iframe 节点等
  • 较正

    • 避免直接对 HTML Entity 解码
    • 使用 DOM Parse 转换,校正不配对的 DOM 标签和属性

CSP

内容安全策略 (CSPopen in new window) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSSopen in new window) 和数据注入攻击等。无论是数据盗取、网站内容污染还是散发恶意软件,这些攻击都是主要的手段。

我们可以通过 CSP 来尽量减少 XSS 攻击。CSP 本质上也是建立白名单,规定了浏览器只能够执行特定来源的代码。

通常可以通过 HTTP Header 中的 Content-Security-Policy 来开启 CSP

  • 只允许加载本站资源

    Content-Security-Policy: default-src 'self'
    
  • 只允许加载 HTTPS 协议图片

    Content-Security-Policy: img-src https://*
    
  • 允许加载任何来源框架

    Content-Security-Policy: child-src 'none'
    

设置了 HttpOnly 的 Cookie 可以防止 JavaScript 脚本调用,就无法通过 document.cookie 获取用户 Cookie 信息。

防御方法举例

  • 使用 encodeURIComponent 对 url 中的参数进行编码(反射型 xss),对一些关键字和特殊字符进行过滤(<>,?,script 等),或对用户输入内容进行 URL 编码(encodeURIComponent);
  • Cookie 不要存放用户名和密码,对 cookie 信息进行 MD5 等算法散列存放,必要时可以将 IP 和 cookie 绑定;
  • 对用户的输入进行过滤(适用于所有类型的 xss 攻击)
  • 对用户的输入使用 innerText 或者 textContent 进行设置,而不是使用 innerHTML 或者 outerHTML 进行设置
  • 服务器端设置 cookie 为 httpOnly 让前端无法通过 js 获取到用户的 cookie
  • 关键请求使用验证码,比如转账请求,避免恶意脚本发送这些关键请求

CSRF 跨站请求伪造 Cross Site Request Forge

CSRF 是一种跨站请求伪造,冒充用户发起请求。简单点说,CSRF 就是利用用户的登录态发起恶意请求。

跨站请求伪造。条件: 1. 用户在 A 网站确实登录过。 2. A 网站接口存在漏洞,会下发登录态。 防御:1. token 验证 2. Referer 验证(页面来源验证) 3. 隐藏令牌

CSRF 攻击原理

完成一次CSRF攻击,必须满足两个必要的条件:

  1. 登录受信任网站A,并在本地生成Cookie。(如果用户没有登录网站A,那么网站B在诱导的时候,请求网站Aapi接口时,会提示你登录)
  2. 在不登出A的情况下,访问危险网站B(其实是利用了网站A的漏洞)。

举个例子,用户同时打开了 A 网站和钓鱼网站。 假设 A 网站中有一个通过 GET 请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口。

CSRF 攻击危害

  • 利用用户登录态
  • 用户不知情
  • 完成业务请求
  • 盗取用户资金
  • 冒充用户发帖背锅
  • 损坏网站名誉

CSRF 防御

服务端的 CSRF 方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数通过验证码的方法

方法一、Token 验证:(用的最多)

  1. 服务器发送给客户端一个token
  2. 客户端提交的表单中带着这个token
  3. 如果这个 token 不合法,那么服务器拒绝这个请求。

方法二:隐藏令牌:

  • token 隐藏在 httphead头中。

方法二和方法一有点像,本质上没有太大区别,只是使用方式上有区别。

方法三、Referer 验证:

Referer 指的是页面请求来源。意思是,只接受本站的请求,服务器才做响应;如果不是,就拦截。

如何防御

  1. Get 请求不对数据进行修改
  2. 不让第三方网站访问到用户 Cookie
  3. 阻止第三方网站请求接口
  4. 请求时附带验证信息,比如验证码或者 Token

预防 CSRF 就是加入各个层级的权限验证,例如现在的购物网站,只要涉及现金交易,肯 定要输入密码或者指纹才行。除此之外,敏感的接口使用 请求而不是 也是很重要 的。

SameSite

可以对 Cookie 设置 SameSite 属性。该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。

验证 Referer

对于需要防范 CSRF 的请求,我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。

Token

服务器下发一个随机 Token,每次发起请求时将 Token 携带上,服务器验证 Token 是否有效。

CSRF 和 XSS 的区别

区别一:

  • CSRF:需要用户先登录网站A,获取 cookie
  • XSS:不需要登录。

区别二:(原理的区别)

  • CSRF:是利用网站A本身的漏洞,去请求网站Aapi
  • XSS:是向网站 A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容。

XSS是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  1. 登录受信任网站 A,并在本地生成 Cookie。
  2. 在不登出 A 的情况下,访问危险网站 B。

XSS 是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF 是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。要完成一次 CSRF 攻击,受害者必须依次完成两个步骤

  1. 登录受信任网站 A,并在本地生成 Cookie
  2. 在不登出 A 的情况下,访问危险网站 B

运营商劫持

假设是被运营商劫持了... 能怎么解决。使用 https。不要使用非 https 的链接。

劫持的本质是 302 重定向,或者是植入恶意的脚本。(运营商劫持或者是别的被恶意的劫持)

被恶意的劫持,修改 wifi 密码。主要是 DNS 解析,注入一段 JavaScript 防止 DNS 修改? 域名映射关系主要是? 阻止重定向

点击劫持

业务页面被 iframe 等标签直接嵌入到盗版页面中去,用户点击时,将事件响应拦截。

解决方式

X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 <frame>, <iframe> 或者 <object>中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。

DENY

表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。

SAMEORIGIN

表示该页面可以在相同域名页面的 frame 中展示。

ALLOW-FROM uri

表示该页面可以在指定来源的 frame 中展示。

DDOS

域名收敛和域名发散

域名收敛:就是将静态资源放在一个域名下。减少 DNS 解析的开销。 域名发散:是将静态资源放在多个子域名下,就可以多线程下载,提高并行度,使客户端加载静态资源更加迅速。

域名发散是 PC 端为了利用浏览器的多线程并行下载能力。而域名收敛多用与移动端,提高性能,因为 dns 解析是是从后向前迭代解析,如果域名过多性能会下降,增加 DNS 的解析开销。

PC 时代为了突破浏览器的域名并发限制,有了域名发散。浏览器有并发限制,是为了防止 DDOS 攻击。

浏览器同一时间可以从一个域名下载多少资源?

浏览器的并发请求数目限制是针对同一域名的。目前,所有浏览器的并发数目一般限制在 10 以内。chrome、opera、firefox、IE8+ 等大概为 6 个,IE6 2 个,IE7 是 4 个。

为什么利用多个域名来存储网站资源会更有效?

CDN 缓存更方便 突破浏览器并发限制 节约 cookie 带宽 节约主域名的连接数,优化页面响应速度 防止不必要的安全问题

Last Updated:
Contributors: yiliang114